import { Request, Response, NextFunction } from 'express';
import ApiResponse from '@/utils/api/api-response.util';
import { isEmpty, isValidStatus } from '../common/validation.util';
import dictService from '@/services/system/dict.service';
import { getLogger } from '@/utils/logger';
import { AuthRequest } from '@/types';

const logger = getLogger('dict-validator', { console: false });
const consoleLogger = getLogger('dict-validator');

/**
 * 验证字典类型创建参数
 */
export const validateDictTypeCreate = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { dictName, dictType, status } = req.body;
    
    // 字典名称验证
    if (isEmpty(dictName)) {
      return ApiResponse.error(res, '字典名称不能为空', 400);
    }
    
    // 字典类型验证
    if (isEmpty(dictType)) {
      return ApiResponse.error(res, '字典类型不能为空', 400);
    }
    
    // 状态验证
    if (!isEmpty(status) && !isValidStatus(status)) {
      return ApiResponse.error(res, '状态值无效', 400);
    }
    
    // 校验字典类型是否唯一
    if (!(await dictService.checkDictTypeUnique(dictType))) {
      consoleLogger.warn('新增字典类型失败: 字典类型已存在', { dictType });
      return ApiResponse.error(res, '新增字典类型失败，字典类型已存在', 400);
    }
    
    logger.debug('字典类型创建参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`字典类型创建验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证字典类型更新参数
 */
export const validateDictTypeUpdate = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { dictId, dictName, dictType, status } = req.body;
    
    if (isEmpty(dictId) || isNaN(parseInt(dictId))) {
      return ApiResponse.error(res, '字典ID不能为空', 400);
    }
    
    if (isEmpty(dictName)) {
      return ApiResponse.error(res, '字典名称不能为空', 400);
    }
    
    if (isEmpty(dictType)) {
      return ApiResponse.error(res, '字典类型不能为空', 400);
    }
    
    if (!isEmpty(status) && !isValidStatus(status)) {
      return ApiResponse.error(res, '状态值无效', 400);
    }
    
    const dId = parseInt(dictId);
    
    // 校验字典类型是否存在
    const dict = await dictService.selectDictTypeById(dId);
    if (!dict) {
      logger.warn('修改字典类型失败: 字典类型不存在', { dictId: dId });
      return ApiResponse.error(res, '修改字典类型失败，字典类型不存在', 400);
    }
    
    // 校验字典类型是否唯一
    if (!(await dictService.checkDictTypeUnique(dictType, dId))) {
      logger.warn('修改字典类型失败: 字典类型已存在', { dictType });
      return ApiResponse.error(res, '修改字典类型失败，字典类型已存在', 400);
    }
    
    logger.debug('字典类型更新参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`字典类型更新验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证字典类型删除参数
 */
export const validateDictTypeRemove = async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const dictIds = req.params.dictId.split(',').map(id => parseInt(id));
    
    if (!dictIds.length || dictIds.some(id => isNaN(id) || id <= 0)) {
      return ApiResponse.error(res, '字典ID无效', 400);
    }
    
    // 校验字典类型是否存在
    for (const dictId of dictIds) {
      const dict = await dictService.selectDictTypeById(dictId);
      if (!dict) {
        logger.warn('删除字典类型失败: 字典类型不存在', { dictId });
        return ApiResponse.error(res, `删除字典类型失败，ID为${dictId}的字典类型不存在`, 400);
      }
    }
    
    logger.debug('字典类型删除参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`字典类型删除验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证获取字典类型详情参数
 */
export const validateDictTypeInfo = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const dictId = parseInt(req.params.dictId);
    
    // 检查dictId是否为有效数字
    if (isNaN(dictId) || dictId <= 0) {
      consoleLogger.warn('获取字典类型详情参数无效', { dictId: req.params.dictId });
      return ApiResponse.error(res, '无效的字典类型ID', 400);
    }
    
    // 校验字典类型是否存在
    const dictType = await dictService.selectDictTypeById(dictId);
    if (!dictType) {
      logger.warn('获取字典类型详情失败: 字典类型不存在', { dictId });
      return ApiResponse.error(res, '字典类型不存在', 400);
    }
    
    logger.debug('获取字典类型详情参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`获取字典类型详情验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证字典数据创建参数
 */
export const validateDictDataCreate = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { dictLabel, dictValue, dictType, dictSort, status } = req.body;
    
    // 字典标签验证
    if (isEmpty(dictLabel)) {
      return ApiResponse.error(res, '字典标签不能为空', 400);
    }
    
    // 字典键值验证
    if (isEmpty(dictValue)) {
      return ApiResponse.error(res, '字典键值不能为空', 400);
    }
    
    // 字典类型验证
    if (isEmpty(dictType)) {
      return ApiResponse.error(res, '字典类型不能为空', 400);
    }
    
    // 字典排序验证
    if (!isEmpty(dictSort) && isNaN(parseInt(dictSort))) {
      return ApiResponse.error(res, '字典排序必须为数字', 400);
    }
    
    // 状态验证
    if (!isEmpty(status) && !isValidStatus(status)) {
      return ApiResponse.error(res, '状态值无效', 400);
    }
    
    // 校验字典类型是否存在
    const dictTypeList = await dictService.selectDictDataByType(dictType);
    if (!dictTypeList && dictTypeList.length === 0) {
      consoleLogger.warn('新增字典数据失败: 字典类型不存在', { dictType });
      return ApiResponse.error(res, '新增字典数据失败，字典类型不存在', 400);
    }
    
    logger.debug('字典数据创建参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`字典数据创建验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证字典数据更新参数
 */
export const validateDictDataUpdate = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const { dictCode, dictLabel, dictValue, dictType, dictSort, status } = req.body;
    
    if (isEmpty(dictCode) || isNaN(parseInt(dictCode))) {
      return ApiResponse.error(res, '字典编码不能为空', 400);
    }
    
    if (isEmpty(dictLabel)) {
      return ApiResponse.error(res, '字典标签不能为空', 400);
    }
    
    if (isEmpty(dictValue)) {
      return ApiResponse.error(res, '字典键值不能为空', 400);
    }
    
    if (isEmpty(dictType)) {
      return ApiResponse.error(res, '字典类型不能为空', 400);
    }
    
    if (!isEmpty(dictSort) && isNaN(parseInt(dictSort))) {
      return ApiResponse.error(res, '字典排序必须为数字', 400);
    }
    
    if (!isEmpty(status) && !isValidStatus(status)) {
      return ApiResponse.error(res, '状态值无效', 400);
    }
    
    const dCode = parseInt(dictCode);
    
    // 校验字典数据是否存在
    const dictData = await dictService.selectDictDataById(dCode);
    if (!dictData) {
      logger.warn('修改字典数据失败: 字典数据不存在', { dictCode: dCode });
      return ApiResponse.error(res, '修改字典数据失败，字典数据不存在', 400);
    }
    
    logger.debug('字典数据更新参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`字典数据更新验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证字典数据删除参数
 */
export const validateDictDataRemove = async (req: AuthRequest, res: Response, next: NextFunction) => {
  try {
    const dictCodes = req.params.dictCode.split(',').map(id => parseInt(id));
    
    if (!dictCodes.length || dictCodes.some(id => isNaN(id) || id <= 0)) {
      return ApiResponse.error(res, '字典编码无效', 400);
    }
    
    // 校验字典数据是否存在
    for (const dictCode of dictCodes) {
      const dictData = await dictService.selectDictDataById(dictCode);
      if (!dictData) {
        logger.warn('删除字典数据失败: 字典数据不存在', { dictCode });
        return ApiResponse.error(res, `删除字典数据失败，编码为${dictCode}的字典数据不存在`, 400);
      }
    }
    
    logger.debug('字典数据删除参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`字典数据删除验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证获取字典数据详情参数
 */
export const validateDictDataInfo = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const dictCode = parseInt(req.params.dictCode);
    
    // 检查dictCode是否为有效数字
    if (isNaN(dictCode) || dictCode <= 0) {
      consoleLogger.warn('获取字典数据详情参数无效', { dictCode: req.params.dictCode });
      return ApiResponse.error(res, '无效的字典数据ID', 400);
    }
    
    // 校验字典数据是否存在
    const dictData = await dictService.selectDictDataById(dictCode);
    if (!dictData) {
      logger.warn('获取字典数据详情失败: 字典数据不存在', { dictCode });
      return ApiResponse.error(res, '字典数据不存在', 400);
    }
    
    logger.debug('获取字典数据详情参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`获取字典数据详情验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
};

/**
 * 验证字典类型参数
 */
export const validateDictType = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const dictType = req.params.dictType;
    
    // 字典类型验证
    if (isEmpty(dictType)) {
      return ApiResponse.error(res, '字典类型不能为空', 400);
    }
    
    // 校验字典类型是否存在
    const dictTypeList = await dictService.selectDictDataByType(dictType);
    if (!dictTypeList || dictTypeList.length === 0) {
      consoleLogger.warn('查询字典数据失败: 字典类型不存在', { dictType });
      return ApiResponse.error(res, '查询字典数据失败，字典类型不存在', 400);
    }
    
    logger.debug('字典类型参数验证通过');
    next();
    return;
  } catch (error) {
    consoleLogger.error(`字典类型参数验证失败: ${error instanceof Error ? error.message : String(error)}`);
    return ApiResponse.error(res, '参数验证失败', 500);
  }
}; 